package utils

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

// 防抖控制变量
var (
	debounceTimer  *time.Timer
	debounceDelay  = 800 * time.Millisecond // 防抖延迟时间
	lastConfigData []byte                   // 上次配置内容（用于比对）
	configMutex    sync.Mutex               // 并发安全锁
)

func InitViper(configName string) (*viper.Viper, error) {
	// 创建独立实例（避免全局污染）
	v := viper.New()

	// 基础配置
	v.SetConfigName(configName) // 通过参数传入配置名
	v.SetConfigType("yaml")

	// 更可靠的路径处理
	executable, err := os.Executable()
	if err != nil {
		return nil, fmt.Errorf("获取可执行文件路径失败: %w", err)
	}
	v.AddConfigPath(filepath.Dir(executable)) // 可执行文件所在目录
	v.AddConfigPath(".")                      // 当前工作目录

	// 读取配置（不 panic）
	if err := v.ReadInConfig(); err != nil {
		return nil, fmt.Errorf("配置读取失败: %w", err)
	}

	// 热加载配置
	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		// 添加防抖处理,防止配置文件的重复读取
		configMutex.Lock()
		defer configMutex.Unlock()
		// 1. 取消未执行的延迟调用
		if debounceTimer != nil {
			debounceTimer.Stop()
		}
		// 2. 启动新的防抖计时器
		debounceTimer = time.AfterFunc(debounceDelay, func() {
			configMutex.Lock()
			defer configMutex.Unlock()

			// 3. 读取最新配置内容
			newData, err := os.ReadFile(e.Name)
			if err != nil {
				log.Printf("无法读取更新后的配置文件: %v", err)
				return
			}

			// 4. 内容比对（避免空变更触发）
			if bytes.Equal(lastConfigData, newData) {
				return
			}

			// 5. 重新加载配置
			if err := v.ReadInConfig(); err != nil {
				log.Printf("配置重载失败: %v", err)
				return
			}

			// 6. 更新防抖状态
			lastConfigData = newData
			log.Printf("配置已生效更新: %s", e.Name)
		})
		// 可在此处触发配置重解析逻辑
	})

	return v, nil
}
